package com.tuanzi.loan.web.bean.settlementsystem;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.starbaba.model.utils.JSONUtils;
import com.tuanzi.loan.business.entity.CurrentUser;
import com.tuanzi.loan.business.entity.settlementsystem.SettlementBill;
import com.tuanzi.loan.business.entity.settlementsystem.SettlementBillAnnex;
import com.tuanzi.loan.business.entity.settlementsystem.SettlementCompany;
import com.tuanzi.loan.business.entity.settlementsystem.SettlementPrepay;
import com.tuanzi.loan.business.entity.system.SystemUser;
import com.tuanzi.loan.business.service.settlementsystem.*;
import com.tuanzi.loan.core.aspect.Debug;
import com.tuanzi.loan.vo.request.settlementsystem.SettlementPrepayRequest;
import com.tuanzi.loan.vo.response.settlementsystem.SettlementPrepayResponse;
import com.tuanzi.loan.web.configuration.JSFListingBean;
import com.tuanzi.loan.web.lazy.settlementsystem.SettlementPrepayLazyDataModel;
import com.tuanzi.loan.workflow.service.WorkflowManagerService;
import com.tuanzi.loan.workflow.service.WorkflowProcessorService;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.UploadedFile;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.faces.bean.ViewScoped;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.tuanzi.loan.business.constants.DictionaryCode.*;

/**
 * @author caiwanlin
 * @create 2018-08-22 17:48
 */
@Slf4j
@Data
@Debug
@Component
@ViewScoped
@EqualsAndHashCode(callSuper = true)
public class SettlementPrepayListBean extends JSFListingBean<SettlementPrepayRequest, SettlementPrepayResponse> {
    @Autowired
    private SettlementCompanyService settlementCompanyService;

    @Autowired
    private SettlementPrepayService settlementPrepayService;

    @Autowired
    private SettlementBillService settlementBillService;

    @Autowired
    private WorkflowManagerService workflowManagerService;

    @Autowired
    private WorkflowProcessorService workflowProcessorService;


    private List<SettlementCompany> companyList;

    private List<SettlementPrepayResponse> selectPrepayList;

    private SettlementPrepay settlementPrepay;

    private SettlementBill settlementBill;//开票

    private List<SystemUser> checkList;//财务核查人

    private String PROCESS_DEF_KEY = "BillSystem";//流程定义key


    private boolean hasSeeRight = true;//是否有参看的权限

    private Long onSeeCompanyId; //当前参看公司的ID

    private List<SettlementBillAnnex> billAnnexList;//上传的附件



    private String header = "新增";

    @PostConstruct
    public void init() throws Exception {
        companyList = settlementCompanyService.getCompanyList();
        settlementPrepay = new SettlementPrepay();
        settlementBill = new SettlementBill();
        billAnnexList = Lists.newArrayList();
        initLazyDataModel();
    }

    private void initLazyDataModel() throws Exception {
        $ = new SettlementPrepayRequest();
        lazyDataModel = new SettlementPrepayLazyDataModel($);
    }

    public void onReset() throws Exception {
        initLazyDataModel();
    }

    public void onSee(Long id){
        header = "编辑";
        settlementPrepay = settlementPrepayService.findOne(id);
        onSeeCompanyId = settlementPrepay.getCompanyId();
        log.info("收款记录查看步骤-onSeeCompanyId="+onSeeCompanyId);
        String name = CurrentUser.get().getName();
        hasSeeRight = name.equals(settlementPrepay.getCreator()) ? true : false;
    }

    public void onAdd() {
        header = "新增";
        hasSeeRight = true;
        settlementPrepay = new SettlementPrepay();
    }

    public void onSave() {
        if (!validate()) return;
        //获取公司名称
        /*String companyName = companyList.parallelStream().filter(c -> {
            if (c.getId() == settlementPrepay.getCompanyId()) return true;
            return false;
        }).map(s -> s.getCompanyName()).findFirst().get();*/

        SettlementCompany con = settlementCompanyService.findOne(settlementPrepay.getCompanyId());
        if (con == null){
            addErrorMessage("查询不到公司");
            return;
        }
        String companyName = con.getCompanyName();
        settlementPrepay.setCompanyName(companyName);
        settlementPrepayService.onSave(settlementPrepay,onSeeCompanyId);
        addSuccessfullyMessage();
        execute("PF('adding').hide();");
        update("prepayForm");
    }

    public void onBill(){
        //是否选择消耗记录
        if (selectPrepayList == null || selectPrepayList.isEmpty()){
            addErrorMessage("请选择预付记录");
            return;
        }
        //判断是否存在后结的预付记录
        long count1 = selectPrepayList.parallelStream().filter(s -> {
            if (s.getPayType() == null) return false;
            return (s.getPayType() != 4);
        }).count();
        if (count1 > 0){
            addErrorMessage("请选择结算方式为（预付）的记录");
            return;
        }

        //判断是否选的未开票的记录
        long count = selectPrepayList.parallelStream().filter(s -> {
            return s.getBillStatus() != BillStatus.NO_BILL.index;
        }).count();
        if (count>0){
            addErrorMessage("请选择未开票的记录");
            return;
        }
        //判断是否选择同一主体开票
        Map<Long, List<SettlementPrepayResponse>> collect = selectPrepayList.parallelStream()
                .collect(Collectors.groupingBy(SettlementPrepayResponse::getCompanyId));
        if (collect.size()>1){
            addErrorMessage("请选择同一个主体开票");
            return;
        }
        billAnnexList = Lists.newArrayList();
        //
        //查询主体
        SettlementPrepayResponse settlementPrepayResponse = selectPrepayList.get(0);
        SettlementCompany settlementCompany = settlementCompanyService.findOne(settlementPrepayResponse.getCompanyId());
        //开票金额
        Double prepayAmount = selectPrepayList.parallelStream().map(s -> s.getPrepayAmount()).collect(Collectors.summingDouble(s->s));
        settlementBill = settlementBillService.structureSettlementBill(settlementCompany);
        settlementBill.setBillAmount(prepayAmount);
        //记录类型(预付)
        settlementBill.setRecordType(RemainType.PREPAY.index);

        checkList = workflowManagerService.findFirstActivitySystemUserProcDefKey(PROCESS_DEF_KEY);
        execute("PF('billing').show();");
        update("prepayForm:bill-dialog");
    }

    public void onSaveBill(){
        String result = settlementBillService.validateBill(settlementBill);
        if (StringUtils.isNotBlank(result)) {
            addErrorMessage(result);
            return;
        }
        //保存
        String checkName = checkList.parallelStream().filter(s -> s.getAccount().equals(settlementBill.getCheckAccount()))
                .map(s -> s.getName()).findFirst().get();
        settlementBill.setCheckName(checkName);//审核人姓名
        List<Long> ids = selectPrepayList.parallelStream().map(s -> (Long) s.getId()).collect(Collectors.toList());
        settlementBill.setDetailList(JSONUtils.toJsonString(selectPrepayList));//保存此时刻明细快照
        settlementBillService.onSave(settlementBill,ids,billAnnexList);
        selectPrepayList = Lists.newArrayList();

        //启动流程
        String account = CurrentUser.get().getAccount();
        String assignee = settlementBill.getCheckAccount();
        String title = "【"+settlementBill.getCompanyName()+"】预付开票流程";
        List<String> businessKeys = Lists.newArrayList(settlementBill.getId().toString());
        Map<String, Object> variables = Maps.newHashMap();
        workflowProcessorService.startProcess(account,assignee,PROCESS_DEF_KEY,title,businessKeys,variables);

        addSuccessfullyMessage();
        execute("PF('billing').hide();");
        update("prepayForm");
    }

    /**
     * 消耗记录上传附件
     * @param event
     */
    public void handleAnnexUpload(FileUploadEvent event){
        SettlementBillAnnex annex = new SettlementBillAnnex();
        UploadedFile file = event.getFile();
        String fileName = file.getFileName();
        annex.setName(fileName);
        annex.setCreator(CurrentUser.get().getName());
        annex.setCreateTime(new Date());
        annex.setFileType(fileName.substring(fileName.lastIndexOf(".")+1));
        String url = this.uploadImg(file);
        annex.setUrl(url);
        billAnnexList.add(annex);
        addSuccessfullyMessage();
        execute("PF('billAnnex').hide();");
        update("prepayForm:bill-dialog");
    }

    /**
     * 删除附件
     */
    public void onDeleteAnnex(Integer index){
        billAnnexList.remove(billAnnexList.get(index));
        update("prepayForm:bill-dialog");
    }


    public boolean validate() {
        if (settlementPrepay.getCompanyId() == null){
            addErrorMessage("没有选择主体");
            return false;
        }
        if(settlementPrepay.getReceiveCompany() == null){
            addErrorMessage("没有选择收款主体");
            return false;
        }
        if (settlementPrepay.getPrepayTime() == null){
            addErrorMessage("没有选择充值日期");
            return false;
        }
        if (settlementPrepay.getPrepayAmount() == null){
            addErrorMessage("充值金额为空");
            return false;
        }
        if (settlementPrepay.getPayType() == null){
            addErrorMessage("没有选择结算方式");
            return false;
        }
        if (settlementPrepay.getPayMode() == null){
            addErrorMessage("没有选择付款方式");
            return false;
        }
        if (StringUtils.isBlank(settlementPrepay.getPayName())){
            addErrorMessage("支付账户为空");
            return false;
        }
        /*if (StringUtils.isBlank(settlementPrepay.getPayAccount())){
            addErrorMessage("支付账号为空");
            return false;
        }*/
        return true;
    }


    @Override
    protected List<String> getDictionaryCodes() {
        return Lists.newArrayList(SETTLEMENT_PAY_MODE, SETTLEMENT_BILLING_CONTENT,SETTLEMENT_BILL_TYPE,SETTLEMENT_RECEIVE_COMPANY,SETTLEMENT_CYCLE,SETTLEMENT_BILL_STATUS);
    }
}
